package com.qf.service.impl;

import com.qf.entity.User;
import com.qf.entity.UserDTO;
import com.qf.mapper.UserMapper;
import com.qf.service.UserService;
import com.qf.util.JwtUtils;
import com.qf.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private RedisUtil redisUtil;
    @Value("${token.expireTime}")
    private int expireTime;
    @Override
    public String login(User user) {

        Authentication authentication=null;
        try{
            //调用loadUserByUsername方法
            authentication=authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword()));
        }catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                throw new RuntimeException("用户认证失败");
            } else {
                throw new RuntimeException(e.getMessage());
            }
        }
        //生成jwt
        Map<String,Object> claims=new HashMap<>();
        claims.put("username",authentication.getName());
        //获取权限
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        Set<String> authoritySet=new HashSet<>();
        authorities.forEach(item->authoritySet.add(item.getAuthority()));
        //权限数据放入claims
        claims.put("perms",authoritySet);
        //生成UUID
        String s=UUID.randomUUID().toString();
        //将uuid的格式转化
        String uuid=s.replace("-","");
        //将uuid存到jwt的token中一份
        claims.put("uuid",uuid);
        String token=jwtUtils.createJwt(claims);
        //uuid当作建存到redis中
        redisUtil.setCacheObject("user:key:"+uuid,token,expireTime, TimeUnit.SECONDS);
        return token;
    }

    @Override
    public List<User> list(UserDTO userDTO) {

        return userMapper.list(userDTO);
    }

    @Override
    public void deleteById(int id) {
         userMapper.deleteById(id);
    }

    @Override
    public void deleteAll(List<Integer> id) {
        userMapper.deleteAll(id);
    }

    @Override
    public void addUser(User user) {
        BCryptPasswordEncoder password=new BCryptPasswordEncoder();
        String pwd=password.encode(user.getPassword());
        user.setPassword(pwd);
        user.setCreateTime(new Date());
        userMapper.addUser(user);
    }

    @Override
    public void updateUser(User user) {
        //修改密码时要将密码加密
        BCryptPasswordEncoder password=new BCryptPasswordEncoder();
        String pwd=password.encode(user.getPassword());
        user.setPassword(pwd);
        userMapper.updateUser(user);
    }
}
